home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Graphics 2D / CopyBits vs. CopyMask / Test.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  11.5 KB  |  470 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        Test.c
  3.  
  4.     Contains:    This snippet drag races CopyBits (using a mask region) and CopyMask 
  5.                 (using a mask BitMap). Which do you think is faster? The results may
  6.                 surprise you.
  7.     
  8.     Written by: Tony Myles
  9.  
  10.     Copyright:    Copyright © 1992-1999 by Apple Computer, Inc., All Rights Reserved.
  11.  
  12.                 You may incorporate this Apple sample source code into your program(s) without
  13.                 restriction. This Apple sample source code has been provided "AS IS" and the
  14.                 responsibility for its operation is yours. You are not permitted to redistribute
  15.                 this Apple sample source code as "Apple sample source code" after having made
  16.                 changes. If you're going to re-distribute the source, we require that you make
  17.                 it clear in the source that the code was descended from Apple sample source
  18.                 code, but that you've made changes.
  19.  
  20.     Change History (most recent first):
  21.                 7/9/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  22.                 
  23.  
  24. */
  25. #include <QuickDraw.h>
  26. //#include <DebugUtils.h>
  27. #include <Dialogs.h>
  28. //#include <GWorldUtils.h>
  29. #include <TextUtils.h>
  30. #include <Resources.h>
  31. #include "Sample.h"
  32. #include "Test.h"
  33. #include <Sound.h>
  34.  
  35.  
  36. ///--------------------------------------------------------------------------------------
  37. //    LetTheGameBegin
  38. ///--------------------------------------------------------------------------------------
  39.  
  40. void LetTheGameBegin(DialogPtr srcDialogP)
  41. {
  42.     OSErr err;
  43.     CGrafPtr saveCPort;
  44.     GDHandle saveGDevice;
  45.     PixMapHandle srcPixMap;
  46.     GWorldPtr pictGWorld = NULL, maskGWorld = NULL;
  47.     GrafPtr offScrnPort = NULL;
  48.     RgnHandle maskRgn = NULL;
  49.     Rect srcRect, dstRect, itemRect;
  50.     short frame;
  51.     long ticks;
  52.     Str255 itemStr;
  53.     PixPatHandle pixPatH;
  54.  
  55.     SetCursor(*GetCursor(watchCursor));
  56.  
  57.     GetGWorld(&saveCPort, &saveGDevice);
  58.     SetGWorld((CGrafPtr)srcDialogP, NULL);
  59.  
  60.     itemStr[0] = 0;
  61.     SetDItemText(srcDialogP, kCopyBitsFramesItem, itemStr);
  62.     SetDItemText(srcDialogP, kCopyBitsTicksItem, itemStr);
  63.     SetDItemText(srcDialogP, kCopyBitsFPSItem, itemStr);
  64.     SetDItemText(srcDialogP, kCopyMaskFramesItem, itemStr);
  65.     SetDItemText(srcDialogP, kCopyMaskTicksItem, itemStr);
  66.     SetDItemText(srcDialogP, kCopyMaskFPSItem, itemStr);
  67.  
  68.     GetDItemRect(srcDialogP, kCopyBitsPictItem, &itemRect);
  69.     OffsetRect(&itemRect, -itemRect.left, -itemRect.top);
  70.     itemRect.right += kFrameCount;
  71.  
  72.     err = CreateOptimumGWorld(&pictGWorld, &itemRect);
  73.  
  74.     if (err == noErr)
  75.     {
  76.         SetGWorld(pictGWorld, NULL);
  77.         srcPixMap = GetGWorldPixMap(pictGWorld);
  78.         (void)LockPixels(srcPixMap);
  79.  
  80.         pixPatH = GetPixPat(kPixPatResID);
  81.  
  82.         if (pixPatH != NULL)
  83.         {
  84.             FillCRect(&itemRect, pixPatH);
  85.             DisposePixPat(pixPatH);
  86.         }
  87.  
  88.         err = CreateGWorldFromPictResource(&maskGWorld, kApplePictResID);
  89.     }
  90.  
  91.     if (err == noErr)
  92.     {
  93.         offScrnPort = NULL;
  94.         err = CreateGrafPortFromPictResource(kApplePictResID, &offScrnPort);
  95.     }
  96.  
  97.     if (err == noErr)
  98.     {
  99.         maskRgn = NewRgn();
  100.     
  101.         err = BitMapToRegion(maskRgn, &offScrnPort->portBits);
  102.     }
  103.  
  104.     if (err == noErr)
  105.     {
  106.         GetDItemRect(srcDialogP, kCopyBitsPictItem, &itemRect);
  107.         OffsetRgn(maskRgn, itemRect.left, itemRect.top);
  108.     
  109.         srcRect = itemRect;
  110.         OffsetRect(&srcRect, -srcRect.left, -srcRect.top);
  111.         dstRect = itemRect;
  112.     
  113.         SetGWorld((CGrafPtr)srcDialogP, NULL);
  114.  
  115.         ticks = TickCount();
  116.  
  117.         for (frame = 0; frame < kFrameCount; frame++)
  118.         {
  119.             CopyBits((BitMapPtr)*srcPixMap, &srcDialogP->portBits,
  120.                         &srcRect, &dstRect, srcCopy, maskRgn);
  121.     
  122.             srcRect.left++;
  123.             srcRect.right++;
  124.         }
  125.     
  126.         ticks = TickCount() - ticks;
  127.     
  128.         NumToString(kFrameCount, itemStr);
  129.         SetDItemText(srcDialogP, kCopyBitsFramesItem, itemStr);
  130.         NumToString(ticks, itemStr);
  131.         SetDItemText(srcDialogP, kCopyBitsTicksItem, itemStr);
  132.         NumToString((ticks < 60) ? kFrameCount : kFrameCount / (ticks / 60), itemStr);
  133.         SetDItemText(srcDialogP, kCopyBitsFPSItem, itemStr);
  134.     
  135.         GetDItemRect(srcDialogP, kCopyMaskPictItem, &itemRect);
  136.         srcRect = itemRect;
  137.         OffsetRect(&srcRect, -srcRect.left, -srcRect.top);
  138.         dstRect = itemRect;
  139.     
  140.         ticks = TickCount();
  141.     
  142.         for (frame = 0; frame < kFrameCount; frame++)
  143.         {
  144.             CopyMask((BitMapPtr)*srcPixMap, &offScrnPort->portBits, &srcDialogP->portBits,
  145.                         &srcRect, &offScrnPort->portRect, &dstRect);
  146.     
  147.             srcRect.left++;
  148.             srcRect.right++;
  149.         }
  150.     
  151.         ticks = TickCount() - ticks;
  152.     
  153.         NumToString(kFrameCount, itemStr);
  154.         SetDItemText(srcDialogP, kCopyMaskFramesItem, itemStr);
  155.         NumToString(ticks, itemStr);
  156.         SetDItemText(srcDialogP, kCopyMaskTicksItem, itemStr);
  157.         NumToString((ticks < 60) ? kFrameCount : kFrameCount / (ticks / 60), itemStr);
  158.         SetDItemText(srcDialogP, kCopyMaskFPSItem, itemStr);
  159.     
  160.         UnlockPixels(srcPixMap);
  161.     }
  162.  
  163.     if (maskRgn != NULL)
  164.         DisposeRgn(maskRgn);
  165.  
  166.     if (offScrnPort != NULL)
  167.         DisposeGrafPort(offScrnPort);
  168.  
  169.     if (maskGWorld != NULL)
  170.         DisposeGWorld(maskGWorld);
  171.  
  172.     if (pictGWorld != NULL)
  173.         DisposeGWorld(pictGWorld);
  174.  
  175.     SetCursor(&qd.arrow);
  176.  
  177.     SysBeep(0);
  178. }
  179.  
  180.  
  181. ///--------------------------------------------------------------------------------------
  182. // CreateOptimumGWorld
  183. //
  184. //    create a new GWorld optimized for speed in copying
  185. //    to the graphics device that intersects the given rect.
  186. ///--------------------------------------------------------------------------------------
  187.  
  188. OSErr CreateOptimumGWorld(GWorldPtr *optGWorld, Rect *devRect)
  189. {
  190.     OSErr err;
  191.     CGrafPtr saveCPort;
  192.     GDHandle saveGDevice;
  193.     GWorldPtr tempGWorld;
  194.     //PixMapHandle pixMapH;
  195.     Rect tempRect = *devRect;
  196.  
  197.     *optGWorld = NULL;
  198.  
  199.     GetGWorld(&saveCPort, &saveGDevice);
  200.  
  201.     LocalToGlobal((Point *)&tempRect.top);
  202.     LocalToGlobal((Point *)&tempRect.bottom);
  203.  
  204.     err = NewGWorld(&tempGWorld, 0, &tempRect, NULL, NULL, 0);
  205.  
  206.     if (err == noErr)
  207.     {
  208.         SetGWorld(tempGWorld, NULL);
  209.         EraseRect(&tempGWorld->portRect);
  210.  
  211.         *optGWorld = tempGWorld;
  212.     }
  213.  
  214.     SetGWorld(saveCPort, saveGDevice);
  215.  
  216.     return err;
  217. }
  218.  
  219.  
  220. ///--------------------------------------------------------------------------------------
  221. //    CreateGWorldFromPict
  222. //
  223. //    creates a offScreen GWorld and draws the specified pict into it
  224. ///--------------------------------------------------------------------------------------
  225.  
  226. OSErr CreateGWorldFromPict(GWorldPtr *pictGWorld, PicHandle pictH)
  227. {
  228.     OSErr err;
  229.     CGrafPtr saveCPort;
  230.     GDHandle saveGDevice;
  231.     GWorldPtr tempGWorld;
  232.     PixMapHandle tempPixMapH;
  233.     Rect pictRect;
  234.  
  235.     *pictGWorld = NULL;
  236.  
  237.     GetGWorld(&saveCPort, &saveGDevice);
  238.  
  239.     pictRect.left = pictRect.top = 0;
  240.     pictRect.right = (**pictH).picFrame.right - (**pictH).picFrame.left;
  241.     pictRect.bottom = (**pictH).picFrame.bottom - (**pictH).picFrame.top;
  242.  
  243.     err = CreateOptimumGWorld(&tempGWorld, &pictRect);
  244.  
  245.     if (err == noErr)
  246.     {
  247.         *pictGWorld = tempGWorld;
  248.  
  249.         SetGWorld(tempGWorld, NULL);
  250.  
  251.         tempPixMapH = GetGWorldPixMap(tempGWorld);
  252.  
  253.         (void)LockPixels(tempPixMapH);
  254.         DrawPicture(pictH, &pictRect);
  255.         UnlockPixels(tempPixMapH);
  256.     }
  257.  
  258.     SetGWorld(saveCPort, saveGDevice);
  259.  
  260.     return err;
  261. }
  262.  
  263.  
  264. ///--------------------------------------------------------------------------------------
  265. // CreateGWorldFromPictResource
  266. ///--------------------------------------------------------------------------------------
  267.  
  268. OSErr CreateGWorldFromPictResource(GWorldPtr *pictGWorldP, short pictResID)
  269. {
  270.     OSErr err;
  271.     PicHandle newPictH;
  272.  
  273.     newPictH = GetPicture(pictResID);
  274.  
  275.     if (newPictH != NULL)
  276.     {
  277.         err = CreateGWorldFromPict(pictGWorldP, newPictH);
  278.  
  279.         ReleaseResource((Handle)newPictH);
  280.     }
  281.  
  282.     return err;
  283. }
  284.  
  285.  
  286. ////--------------------------------------------------------------------------------------
  287. //    CreateGrafPort
  288. //
  289. // originally written by Forrest Tanaka
  290. ////--------------------------------------------------------------------------------------
  291.  
  292. OSErr CreateGrafPort(Rect *newPortRect, GrafPtr *newPort)
  293. {
  294.     OSErr err = noErr;
  295.     GrafPtr savePort;        // save port for later restore
  296.     GrafPtr localPort;    // local copy of GrafPort
  297.     Rect localPortRect;    // local copy of bounds
  298.  
  299.     *newPort = NULL;
  300.  
  301.         // save off the current port
  302.     GetPort(&savePort);
  303.  
  304.         // set the top-left corner of bounds to (0,0)
  305.     localPortRect = *newPortRect;
  306.     OffsetRect(&localPortRect, -newPortRect->left, -newPortRect->top);
  307.  
  308.         // allocate a new GrafPort
  309.     localPort = (GrafPtr)NewPtrClear(sizeof(GrafPort));
  310.  
  311.     if (localPort != NULL)
  312.     {
  313.             // initialize the new port and make the current port
  314.         OpenPort(localPort);
  315.         SetPort(localPort);
  316.         ForeColor(blackColor);
  317.         BackColor(whiteColor);
  318.  
  319.             // initialize and allocate the bitmap
  320.         localPort->portBits.bounds = localPortRect;
  321.           localPort->portBits.rowBytes = ((localPortRect.right + 15) >> 4) << 1;
  322.         localPort->portBits.baseAddr = NewPtrClear(localPort->portBits.rowBytes *
  323.                                                                                             (long)localPortRect.bottom);
  324.  
  325.         if (localPort->portBits.baseAddr != NULL)
  326.         {
  327.                 // clean up the new port
  328.             localPort->portRect = localPortRect;
  329.             ClipRect(&localPortRect);
  330.             RectRgn(localPort->visRgn, &localPortRect);
  331.             EraseRect(&localPortRect);
  332.  
  333.             *newPort = localPort;
  334.         }
  335.         else // allocation failed
  336.         {
  337.                 // capture the error
  338.             err = MemError();
  339.  
  340.                 // deallocate the port
  341.             ClosePort(localPort);
  342.             DisposePtr((Ptr)localPort);
  343.         }
  344.     }
  345.     else
  346.     {
  347.         err = MemError();
  348.     }
  349.  
  350.     SetPort(savePort);
  351.  
  352.     return err;
  353. }
  354.  
  355.  
  356. ////--------------------------------------------------------------------------------------
  357. //    CreateGrafPortFromPictResource
  358. //
  359. //    this routine will set up an offscreen port, and draw a pict into it
  360. //    the offscreen port is the exact size of the pict
  361. ///--------------------------------------------------------------------------------------
  362.  
  363. OSErr CreateGrafPortFromPictResource(short pictID, GrafPtr *offScrnPort)
  364. {
  365.     OSErr            err;
  366.     GrafPtr        savePort;
  367.     PicHandle    pictH;
  368.     Rect            tmpRect;
  369.  
  370.     GetPort(&savePort);
  371.  
  372.     pictH = GetPicture(pictID);
  373.  
  374.     if (pictH != NULL)
  375.     {
  376.         tmpRect.left = tmpRect.top = 0;
  377.         tmpRect.right = (**pictH).picFrame.right - (**pictH).picFrame.left;
  378.         tmpRect.bottom = (**pictH).picFrame.bottom - (**pictH).picFrame.top;
  379.  
  380.             //    create a port
  381.         err = CreateGrafPort(&tmpRect, offScrnPort);
  382.  
  383.         if (err == noErr)
  384.         {
  385.             SetPort(*offScrnPort);
  386.  
  387.                 //    draw the picture
  388.             DrawPicture(pictH, &tmpRect);
  389.         }
  390.  
  391.         ReleaseResource((Handle)pictH);
  392.     }
  393.     else
  394.     {
  395.         err = ResError();
  396.         
  397.         if (err == noErr)
  398.         {
  399.             err = resNotFound;
  400.         }
  401.     }
  402.  
  403.     SetPort(savePort);
  404.  
  405.     return err;
  406. }
  407.  
  408.  
  409. ////--------------------------------------------------------------------------------------
  410. //    DisposeGrafPort
  411. //
  412. // originally written by Forrest Tanaka
  413. ///--------------------------------------------------------------------------------------
  414.  
  415. void DisposeGrafPort(GrafPtr doomedPort)
  416. {
  417.     ClosePort(doomedPort);
  418.     DisposePtr(doomedPort->portBits.baseAddr);
  419.     DisposePtr((Ptr)doomedPort);
  420. }
  421.  
  422.  
  423. ///--------------------------------------------------------------------------------------
  424. // GetDItemText
  425. //
  426. //    get the text of a dialog item
  427. ///--------------------------------------------------------------------------------------
  428.  
  429. void GetDItemText(DialogPtr dlgP, short itemNum, Str255 iStr)
  430. {
  431.     short itemType;
  432.     Rect itemRect;
  433.     Handle itemH;
  434.  
  435.     GetDialogItem(dlgP, itemNum, &itemType, &itemH, &itemRect);
  436.     GetDialogItemText(itemH, iStr);                
  437. }
  438.  
  439.  
  440. ///--------------------------------------------------------------------------------------
  441. // SetDItemText
  442. //
  443. //    set the text of a dialog item
  444. ///--------------------------------------------------------------------------------------
  445.  
  446. void SetDItemText(DialogPtr dlgP, short itemNum, Str255 iStr)
  447. {
  448.     short itemType;
  449.     Rect itemRect;
  450.     Handle itemH;
  451.  
  452.     GetDialogItem(dlgP, itemNum, &itemType, &itemH, &itemRect);
  453.     SetDialogItemText(itemH, iStr);                
  454. }
  455.  
  456.  
  457. ///--------------------------------------------------------------------------------------
  458. // GetDItemRect
  459. //
  460. //    return the rect of a dialog item
  461. ///--------------------------------------------------------------------------------------
  462.  
  463. void GetDItemRect(DialogPtr dlgP, short itemNum, Rect *itemRect)
  464. {
  465.     short itemType;
  466.     Handle itemH;
  467.  
  468.     GetDialogItem(dlgP, itemNum, &itemType, &itemH, itemRect);
  469. }
  470.